﻿package skeletalAnimation
{
	import utils.FPSCounter;
	import flash.geom.Vector3D;
	import flash.geom.Matrix3D;
	import flash.text.TextFieldAutoSize;
	import com.dncompute.graphics.ArrowStyle;
	import flash.geom.Point;
	import com.dncompute.graphics.GraphicsUtil;
	import flash.display.Shape;
	import flash.utils.getTimer;
	import flash.events.MouseEvent;
	import flash.text.TextFormat;
	import com.bit101.components.HUISlider;
	import flash.text.TextField;
	import flash.display.StageScaleMode;
	import flash.display.StageAlign;
	import flash.events.Event;
	import flash.display.Sprite;
	
	public class Main extends Sprite
	{
		private var gui:Sprite;
			private var fps:FPSCounter;
			private var cross:Sprite;
			private var tfFrames:TextField;
			private var labelX:TextField;
			private var labelY:TextField;
			private var sliderAnimationSpeed:HUISlider;
			
			private var labelFigure:TextField;
			private var sliderFigureShoulderWidth:HUISlider;
			private var sliderFigureWaistWidth:HUISlider;
			private var sliderFigureHipWidth:HUISlider;
			private var sliderFigureLegsHeight:HUISlider;
			private var sliderFigureHandsHeight:HUISlider;
			private var sliderFigureIncline:HUISlider;
			
		private var skeletAnimation:SkeletalAnimation;
		
		private var msx:Number;
		private var msy:Number;
		private var button:Boolean = false;
		
		public function Main()
		{
			trace(this);

			addEventListener(Event.ENTER_FRAME, init);
			
		}
		
		private function init(e:Event=null):void
		{
			if(stage.stageWidth == 0)
			{
				return;
			}
			else
			{
				removeEventListener(Event.ENTER_FRAME, init);
			}
			
			
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.stageFocusRect = false;
			
			skeletAnimation = addChild( new SkeletalAnimation() ) as SkeletalAnimation;
			
			
			setupGUI();
			setupGUIEvents();
			draw();
			startTimer();			
		}
		
		private function setupGUI():void
		{
			var sliderWidth:int = 200;
			
			gui = addChildAt( new Sprite(), 0 )  as Sprite;
			
			fps = addChild( new FPSCounter() ) as FPSCounter;
			
			cross = gui.addChild( new Sprite() ) as Sprite;
			
			tfFrames = gui.addChild( new TextField() ) as TextField;
				tfFrames.wordWrap = tfFrames.multiline = false;
				tfFrames.defaultTextFormat = new TextFormat("_sans", 12, 0x454545);
				tfFrames.width = 200;
				tfFrames.height = 18;
				tfFrames.border = true;
			
			labelX = gui.addChild( new TextField() ) as TextField;
				labelX.wordWrap = labelX.multiline = labelX.mouseEnabled = labelX.selectable = false;
				labelX.autoSize = TextFieldAutoSize.LEFT;
				labelX.defaultTextFormat = new TextFormat("_sans", 40, 0xe0e0e0, true);
				labelX.text = "rotate X";
				labelX.setTextFormat(new TextFormat("_sans", 12, 0x686868), 0, labelX.text.length-2);
				
			labelY = gui.addChild( new TextField() ) as TextField;
				labelY.wordWrap = labelY.multiline = labelY.mouseEnabled = labelY.selectable = false;
				labelY.autoSize = TextFieldAutoSize.LEFT;
				labelY.defaultTextFormat = new TextFormat("_sans", 40, 0xe0e0e0, true);
				labelY.text = "Y";
			
			sliderAnimationSpeed = gui.addChild( new HUISlider() ) as HUISlider;
				sliderAnimationSpeed.label = "loop time(sec.)";
				sliderAnimationSpeed.minimum = 0.5;
				sliderAnimationSpeed.maximum = 12;
				sliderAnimationSpeed.width = sliderWidth;				
				sliderAnimationSpeed.value = skeletAnimation.actionLoopTime;
				
			labelFigure = gui.addChild( new TextField() ) as TextField;
				labelFigure.wordWrap = labelFigure.multiline = labelFigure.mouseEnabled = labelFigure.selectable = false;
				labelFigure.autoSize = TextFieldAutoSize.LEFT;
				labelFigure.defaultTextFormat = new TextFormat("_sans", 12, 0x343434, true);
				labelFigure.text = "some figure parameters";
				
			sliderFigureShoulderWidth = gui.addChild( new HUISlider() ) as HUISlider;
				sliderFigureShoulderWidth.label = "shoulder width";
				sliderFigureShoulderWidth.minimum = Math.abs(2*skeletAnimation.walk[skeletAnimation.SHOULDER][0][0])*.5;
				sliderFigureShoulderWidth.maximum = Math.abs(2*skeletAnimation.walk[skeletAnimation.SHOULDER][0][0])*1.3;
				sliderFigureShoulderWidth.width = sliderWidth;				
				sliderFigureShoulderWidth.value = Math.abs(2*skeletAnimation.walk[skeletAnimation.SHOULDER][0][0]);
				
			sliderFigureWaistWidth = gui.addChild( new HUISlider() ) as HUISlider;
				sliderFigureWaistWidth.label = "waist width";
				sliderFigureWaistWidth.minimum = Math.abs(2*skeletAnimation.walk[skeletAnimation.WAIST][0][0])*.7;
				sliderFigureWaistWidth.maximum = Math.abs(2*skeletAnimation.walk[skeletAnimation.WAIST][0][0])*2;
				sliderFigureWaistWidth.width = sliderWidth;				
				sliderFigureWaistWidth.value = Math.abs(2*skeletAnimation.walk[skeletAnimation.WAIST][0][0]);
				
			sliderFigureHipWidth = gui.addChild( new HUISlider() ) as HUISlider;
				sliderFigureHipWidth.label = "hip width";
				sliderFigureHipWidth.minimum = Math.abs(2*skeletAnimation.walk[skeletAnimation.HIP][0][0])*.7;
				sliderFigureHipWidth.maximum = Math.abs(2*skeletAnimation.walk[skeletAnimation.HIP][0][0])*1.5;
				sliderFigureHipWidth.width = sliderWidth;				
				sliderFigureHipWidth.value = Math.abs(2*skeletAnimation.walk[skeletAnimation.HIP][0][0]);
				
			sliderFigureLegsHeight = gui.addChild( new HUISlider() ) as HUISlider;
				sliderFigureLegsHeight.label = "legs length";
				sliderFigureLegsHeight.minimum = (Math.abs(skeletAnimation.walk[skeletAnimation.HEEL][0][1]) - Math.abs(skeletAnimation.walk[skeletAnimation.HIP][0][1]))*.5;
				sliderFigureLegsHeight.maximum = (Math.abs(skeletAnimation.walk[skeletAnimation.HEEL][0][1]) - Math.abs(skeletAnimation.walk[skeletAnimation.HIP][0][1]))*1.5;
				sliderFigureLegsHeight.width = sliderWidth;				
				sliderFigureLegsHeight.value = (Math.abs(skeletAnimation.walk[skeletAnimation.HEEL][0][1]) - Math.abs(skeletAnimation.walk[skeletAnimation.HIP][0][1]));
				
			sliderFigureHandsHeight = gui.addChild( new HUISlider() ) as HUISlider;
				sliderFigureHandsHeight.label = "hands length";
				sliderFigureHandsHeight.minimum = Math.abs(skeletAnimation.walk[skeletAnimation.HAND][0][1] - skeletAnimation.walk[skeletAnimation.SHOULDER][0][1])*.5;
				sliderFigureHandsHeight.maximum = Math.abs(skeletAnimation.walk[skeletAnimation.HAND][0][1] - skeletAnimation.walk[skeletAnimation.SHOULDER][0][1])*1.5;
				sliderFigureHandsHeight.width = sliderWidth;				
				sliderFigureHandsHeight.value = Math.abs(skeletAnimation.walk[skeletAnimation.HAND][0][1] - skeletAnimation.walk[skeletAnimation.SHOULDER][0][1]);
				
			sliderFigureIncline = gui.addChild( new HUISlider() ) as HUISlider;
				sliderFigureIncline.label = "incline";
				sliderFigureIncline.minimum = Math.atan2(skeletAnimation.walk[skeletAnimation.SHOULDER][0][1]-skeletAnimation.walk[skeletAnimation.WAIST][0][1], skeletAnimation.walk[skeletAnimation.SHOULDER][0][2]-skeletAnimation.walk[skeletAnimation.WAIST][0][2]) - Math.PI/18;
				sliderFigureIncline.maximum = Math.atan2(skeletAnimation.walk[skeletAnimation.SHOULDER][0][1]-skeletAnimation.walk[skeletAnimation.WAIST][0][1], skeletAnimation.walk[skeletAnimation.SHOULDER][0][2]-skeletAnimation.walk[skeletAnimation.WAIST][0][2]) + Math.PI/3;
				sliderFigureIncline.width = sliderWidth;
				sliderFigureIncline.value = Math.atan2(skeletAnimation.walk[skeletAnimation.SHOULDER][0][1]-skeletAnimation.walk[skeletAnimation.WAIST][0][1], skeletAnimation.walk[skeletAnimation.SHOULDER][0][2]-skeletAnimation.walk[skeletAnimation.WAIST][0][2]);
		}
		private function setupGUIEvents():void
		{
			cross.addEventListener(MouseEvent.MOUSE_DOWN,mDown);
			stage.addEventListener(MouseEvent.MOUSE_UP,mUp);
			
			gui.addEventListener(Event.CHANGE, handleGUIChange, true);
			
			stage.addEventListener(Event.RESIZE, draw);
			
			startTimer();
		}
		private function draw(e:Event=null):void
		{
			var padding:Number = 50;
			var w:Number = (stage.stageWidth/2 - padding*2) ;
			var h:Number = stage.stageHeight * w/stage.stageWidth;
			
			var ars:ArrowStyle = new ArrowStyle();
				ars.headLength = 80;
				ars.headWidth = 120;
				ars.shaftThickness = 80;
			var arrowColor:Number = 0xcfcfcf;
			
			cross.graphics.clear();
			cross.graphics.beginFill(arrowColor);
			GraphicsUtil.drawArrow(cross.graphics, new Point(stage.stageWidth/2, stage.stageHeight/2), new Point(0, stage.stageHeight/2), ars);
			cross.graphics.endFill();
			cross.graphics.beginFill(arrowColor);
			GraphicsUtil.drawArrow(cross.graphics, new Point(stage.stageWidth/2, stage.stageHeight/2), new Point(stage.stageWidth, stage.stageHeight/2) , ars);
			cross.graphics.endFill();
			cross.graphics.beginFill(arrowColor);
			GraphicsUtil.drawArrow(cross.graphics, new Point(stage.stageWidth/2, stage.stageHeight/2), new Point(stage.stageWidth/2, 0) , ars);
			cross.graphics.endFill();
			cross.graphics.beginFill(arrowColor);
			GraphicsUtil.drawArrow(cross.graphics, new Point(stage.stageWidth/2, stage.stageHeight/2), new Point(stage.stageWidth/2, stage.stageHeight) , ars);
			cross.graphics.endFill();
			
			labelX.x = int(stage.stageWidth - labelX.width - ars.headLength);
			labelX.y = int((stage.stageHeight - labelX.height)/2);
			labelY.x = int((stage.stageWidth - labelY.width)/2);
			labelY.y = int(stage.stageHeight - labelY.height - ars.headLength);
			
			skeletAnimation.x = stage.stageWidth/2;
			skeletAnimation.y = stage.stageHeight/2;
			
			tfFrames.x = 2;
			tfFrames.y = 22;	
			
			sliderAnimationSpeed.x = 2;// + (actionLoopTime * sliderWidth/animationsSpeedMax);
			sliderAnimationSpeed.y = tfFrames.y + tfFrames.height + 2;// + (valueAnimationSpeed.height + sliderAnimationSpeed.height)/2;
			
			labelFigure.x = 2;
			labelFigure.y = sliderAnimationSpeed.y + sliderAnimationSpeed.height + 2;
			
			sliderFigureShoulderWidth.x = 2;
			sliderFigureShoulderWidth.y = labelFigure.y + labelFigure.height;
			
			sliderFigureWaistWidth.x = 2;
			sliderFigureWaistWidth.y = sliderFigureShoulderWidth.y + sliderFigureShoulderWidth.height;
			
			sliderFigureHipWidth.x = 2;
			sliderFigureHipWidth.y = sliderFigureWaistWidth.y + sliderFigureWaistWidth.height;
			
			sliderFigureLegsHeight.x = 2;
			sliderFigureLegsHeight.y = sliderFigureHipWidth.y + sliderFigureHipWidth.height;
			
			sliderFigureHandsHeight.x = 2;
			sliderFigureHandsHeight.y = sliderFigureLegsHeight.y + sliderFigureLegsHeight.height;
			
			sliderFigureIncline.x = 2;
			sliderFigureIncline.y = sliderFigureHandsHeight.y + sliderFigureHandsHeight.height;
		}
		private function mDown(evt:Event):void
		{
			msx=this.mouseX;
			msy=this.mouseY;
			button=true;
		}
		private function mUp(evt:Event):void
		{
			button=false;
		}
		private function handleGUIChange(e:Event):void
		{
			var d1:Number;
			var d2:Number;
			
			// -----------
			
			switch(e.target)
			{
				case sliderAnimationSpeed:
					skeletAnimation.actionLoopTime = sliderAnimationSpeed.value;
				break;
				case sliderFigureShoulderWidth:			
					changeFigureWidth(skeletAnimation.SHOULDER, sliderFigureShoulderWidth.value);
				break;
				case sliderFigureWaistWidth:
					changeFigureWidth(skeletAnimation.WAIST, sliderFigureWaistWidth.value);
				break;
				case sliderFigureHipWidth:
					changeFigureWidth(skeletAnimation.HIP, sliderFigureHipWidth.value);
				break;
				case sliderFigureLegsHeight:
					var lengthNormal:Number = (Math.abs(skeletAnimation.walk[skeletAnimation.HEEL][0][1]) - Math.abs(skeletAnimation.walk[skeletAnimation.HIP][0][1]));
					var scale:Number = sliderFigureLegsHeight.value/lengthNormal;
					var scaleCurrent:Number = (Math.abs(skeletAnimation.actionArray[skeletAnimation.HEEL][0][1]) - Math.abs(skeletAnimation.actionArray[skeletAnimation.HIP][0][1])) / (Math.abs(skeletAnimation.walk[skeletAnimation.HEEL][0][1]) - Math.abs(skeletAnimation.actionArray[skeletAnimation.HIP][0][1]));
					var scaleResult:Number = scale/scaleCurrent;
					
					var llength:int = skeletAnimation.walk[0].length;
					for(var l:int=0; l<llength; l++)
					{
						d1 = skeletAnimation.actionArray[skeletAnimation.HIP][l][1];
						d2 = skeletAnimation.actionArray[skeletAnimation.HIP][l][2];	
						
						skeletAnimation.actionArray[skeletAnimation.HEEL][l][1] = scaleValue(skeletAnimation.actionArray[skeletAnimation.HEEL][l][1], scaleResult, d1);
						skeletAnimation.actionArray[skeletAnimation.HEEL][l][2] = scaleValue(skeletAnimation.actionArray[skeletAnimation.HEEL][l][2], scaleResult, d2);
						
						skeletAnimation.actionArray[skeletAnimation.KNEE][l][1] = scaleValue(skeletAnimation.actionArray[skeletAnimation.KNEE][l][1], scaleResult, d1);
						skeletAnimation.actionArray[skeletAnimation.KNEE][l][2] = scaleValue(skeletAnimation.actionArray[skeletAnimation.KNEE][l][2], scaleResult, d2);
						
						skeletAnimation.actionArray[skeletAnimation.TOE][l][1] = scaleValue(skeletAnimation.actionArray[skeletAnimation.TOE][l][1], scaleResult, d1);
						skeletAnimation.actionArray[skeletAnimation.TOE][l][2] = scaleValue(skeletAnimation.actionArray[skeletAnimation.TOE][l][2], scaleResult, d2);
						
						skeletAnimation.actionArray[skeletAnimation.HEEL+skeletAnimation.actionPointsNumber][l][1] = scaleValue(skeletAnimation.actionArray[skeletAnimation.HEEL+skeletAnimation.actionPointsNumber][l][1], scaleResult, d1);
						skeletAnimation.actionArray[skeletAnimation.HEEL+skeletAnimation.actionPointsNumber][l][2] = scaleValue(skeletAnimation.actionArray[skeletAnimation.HEEL+skeletAnimation.actionPointsNumber][l][2], scaleResult, d2);
						
						skeletAnimation.actionArray[skeletAnimation.KNEE+skeletAnimation.actionPointsNumber][l][1] = scaleValue(skeletAnimation.actionArray[skeletAnimation.KNEE+skeletAnimation.actionPointsNumber][l][1], scaleResult, d1);
						skeletAnimation.actionArray[skeletAnimation.KNEE+skeletAnimation.actionPointsNumber][l][2] = scaleValue(skeletAnimation.actionArray[skeletAnimation.KNEE+skeletAnimation.actionPointsNumber][l][2], scaleResult, d2);
						
						skeletAnimation.actionArray[skeletAnimation.TOE+skeletAnimation.actionPointsNumber][l][1] = scaleValue(skeletAnimation.actionArray[skeletAnimation.TOE+skeletAnimation.actionPointsNumber][l][1], scaleResult, d1);
						skeletAnimation.actionArray[skeletAnimation.TOE+skeletAnimation.actionPointsNumber][l][2] = scaleValue(skeletAnimation.actionArray[skeletAnimation.TOE+skeletAnimation.actionPointsNumber][l][2], scaleResult, d2);
					}
				break;
				case sliderFigureHandsHeight:
					var lengthNormal1:Number = Math.abs(skeletAnimation.walk[skeletAnimation.HAND][0][1] - skeletAnimation.walk[skeletAnimation.SHOULDER][0][1]);
					var scale1:Number = sliderFigureHandsHeight.value/lengthNormal1;
					var scaleCurrent1:Number = (skeletAnimation.actionArray[skeletAnimation.HAND][0][1] - skeletAnimation.actionArray[skeletAnimation.SHOULDER][0][1]) / (skeletAnimation.walk[skeletAnimation.HAND][0][1] - skeletAnimation.actionArray[skeletAnimation.SHOULDER][0][1]);
					var scaleResult1:Number = Math.abs(scale1/scaleCurrent1);
					
					var llength1:int = skeletAnimation.walk[0].length;
					
					for(var l1:int=0; l1<llength1; l1++)
					{
						d1 = skeletAnimation.actionArray[skeletAnimation.SHOULDER][l1][1];
						d2 = skeletAnimation.actionArray[skeletAnimation.SHOULDER][l1][2];	
						
						skeletAnimation.actionArray[skeletAnimation.ELLBOW][l1][1] = scaleValue(skeletAnimation.actionArray[skeletAnimation.ELLBOW][l1][1], scaleResult1, d1);
						skeletAnimation.actionArray[skeletAnimation.ELLBOW][l1][2] = scaleValue(skeletAnimation.actionArray[skeletAnimation.ELLBOW][l1][2], scaleResult1, d2);
						
						skeletAnimation.actionArray[skeletAnimation.ELLBOW+skeletAnimation.actionPointsNumber][l1][1] = scaleValue(skeletAnimation.actionArray[skeletAnimation.ELLBOW+skeletAnimation.actionPointsNumber][l1][1], scaleResult1, d1);
						skeletAnimation.actionArray[skeletAnimation.ELLBOW+skeletAnimation.actionPointsNumber][l1][2] = scaleValue(skeletAnimation.actionArray[skeletAnimation.ELLBOW+skeletAnimation.actionPointsNumber][l1][2], scaleResult1, d2);
						
						skeletAnimation.actionArray[skeletAnimation.HAND][l1][1] = scaleValue(skeletAnimation.actionArray[skeletAnimation.HAND][l1][1], scaleResult1, d1);
						skeletAnimation.actionArray[skeletAnimation.HAND][l1][2] = scaleValue(skeletAnimation.actionArray[skeletAnimation.HAND][l1][2], scaleResult1, d2);
						
						skeletAnimation.actionArray[skeletAnimation.HAND+skeletAnimation.actionPointsNumber][l1][1] = scaleValue(skeletAnimation.actionArray[skeletAnimation.HAND+skeletAnimation.actionPointsNumber][l1][1], scaleResult1, d1);
						skeletAnimation.actionArray[skeletAnimation.HAND+skeletAnimation.actionPointsNumber][l1][2] = scaleValue(skeletAnimation.actionArray[skeletAnimation.HAND+skeletAnimation.actionPointsNumber][l1][2], scaleResult1, d2);
					}
				break;
				case sliderFigureIncline:
					var currentRotation:Number = Math.atan2(skeletAnimation.actionArray[skeletAnimation.SHOULDER][0][1]-skeletAnimation.actionArray[skeletAnimation.WAIST][0][1], skeletAnimation.actionArray[skeletAnimation.SHOULDER][0][2]-skeletAnimation.actionArray[skeletAnimation.WAIST][0][2]);
					var delta:Number = currentRotation - sliderFigureIncline.value;
					var v:Vector3D;
					var mlength:int = skeletAnimation.walk[0].length;
					for(var m:int=0; m<mlength; m++)
					{
						var matrix:Matrix3D = new Matrix3D();
							matrix.appendRotation(delta*180/Math.PI
								, Vector3D.X_AXIS
								, new Vector3D
								(
									(skeletAnimation.actionArray[skeletAnimation.WAIST][0][0] + skeletAnimation.actionArray[skeletAnimation.WAIST+skeletAnimation.actionPointsNumber][0][0])/2
									,(skeletAnimation.actionArray[skeletAnimation.WAIST][0][1] + skeletAnimation.actionArray[skeletAnimation.WAIST+skeletAnimation.actionPointsNumber][0][1])/2
									,(skeletAnimation.actionArray[skeletAnimation.WAIST][0][2] + skeletAnimation.actionArray[skeletAnimation.WAIST+skeletAnimation.actionPointsNumber][0][2])/2
								));
							
							v = matrix.transformVector(new Vector3D(skeletAnimation.actionArray[skeletAnimation.SHOULDER][m][0], skeletAnimation.actionArray[skeletAnimation.SHOULDER][m][1], skeletAnimation.actionArray[skeletAnimation.SHOULDER][m][2]));
							skeletAnimation.actionArray[skeletAnimation.SHOULDER][m][0] = v.x;
							skeletAnimation.actionArray[skeletAnimation.SHOULDER][m][1] = v.y;
							skeletAnimation.actionArray[skeletAnimation.SHOULDER][m][2] = v.z;
							
							v = matrix.transformVector(new Vector3D(skeletAnimation.actionArray[skeletAnimation.SHOULDER+skeletAnimation.actionPointsNumber][m][0], skeletAnimation.actionArray[skeletAnimation.SHOULDER+skeletAnimation.actionPointsNumber][m][1], skeletAnimation.actionArray[skeletAnimation.SHOULDER+skeletAnimation.actionPointsNumber][m][2]));
							skeletAnimation.actionArray[skeletAnimation.SHOULDER+skeletAnimation.actionPointsNumber][m][0] = v.x;
							skeletAnimation.actionArray[skeletAnimation.SHOULDER+skeletAnimation.actionPointsNumber][m][1] = v.y;
							skeletAnimation.actionArray[skeletAnimation.SHOULDER+skeletAnimation.actionPointsNumber][m][2] = v.z;
							
							v = matrix.transformVector(new Vector3D(skeletAnimation.actionArray[skeletAnimation.HEAD][m][0], skeletAnimation.actionArray[skeletAnimation.HEAD][m][1], skeletAnimation.actionArray[skeletAnimation.HEAD][m][2]));
							skeletAnimation.actionArray[skeletAnimation.HEAD][m][0] = v.x;
							skeletAnimation.actionArray[skeletAnimation.HEAD][m][1] = v.y;
							skeletAnimation.actionArray[skeletAnimation.HEAD][m][2] = v.z;
					}					
				break;				
			}
		}
		private function scaleValue(value:Number, scale:Number, delta:Number):Number
		{
			value -= delta;
			value *= scale;
			value += delta;
			
			return value;
		}
		private function changeFigureWidth(type:int, value:Number):void
		{
			var w0:Array = skeletAnimation.walk[type];
			var w1:Array = skeletAnimation.actionArray[type];
			var w2:Array = skeletAnimation.actionArray[type+skeletAnimation.actionPointsNumber];
			var wd:Number = value/2 - Math.abs(w0[0][0]);
			
			for(var w:int=0; w<w0.length; w++)
			{
				w1[w][0] -= wd;
				w2[w][0] += wd;
			}
		}
		
		// =====================
		
		private var _shape:Shape = new Shape();
		private var _time:Number;
		private var _running:Boolean = false;
		
		private function startTimer():void
		{
			_shape.addEventListener( Event.ENTER_FRAME, frameUpdate, false, 0, true );
			_time = getTimer();
			_running = true;
		}
		
		private function stopTimer():void
		{
			_shape.removeEventListener( Event.ENTER_FRAME, frameUpdate );
			_running = false;
		}

		private function frameUpdate( ev:Event ):void
		{
			var oldTime:int = _time;
			_time = getTimer();
			var frameTime:Number = ( _time - oldTime ) * 0.001;
			
			if(button)
			{
				skeletAnimation.rotY+=(msx-this.mouseX)/4000;
				skeletAnimation.rotX+=(msy-this.mouseY)/4000;
			}
			
			skeletAnimation.update(frameTime);
			
			tfFrames.defaultTextFormat = tfFrames.defaultTextFormat;
			tfFrames.text = "current frame "+skeletAnimation.currentFrame;
		}
	}
}
